<?php
// +----------------------------------------------------------------------
// | PHP [ JUST YOU ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2017 http://www.jyphp.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: FlyingPig <flyingpigfp@163.com>
// +----------------------------------------------------------------------

namespace App\Logic;


use App\Common\Logger;
use App\Exceptions\ApiException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class PayCallBackLogic extends Logic
{

    /**
     * 支付回调 统一处理(支付成功的前提下)
     * @param $out_trade_no
     * @param string $xml
     * @throws ApiException
     */
    public function handle($out_trade_no, $xml = '')
    {
        $object = DB::table('t_pay_info')->where('order_id', $out_trade_no)->first(['uid', 'goods_id', 'order_status', 'goods_type', 'pay_type']);

        //已经处理过 直接中断
        if ($object->order_status == 1) {
            return;
        }

        switch ($object->goods_type) {
            case 1 :
                $pay_type_string = [1 => '微信支付', 2 => '支付宝支付', 3 => '苹果支付', 4 => '移动支付', 5 => '微信代扣'];
                DiamondsLogic::instance()->handlePayCallBack($object->goods_id, $out_trade_no, $xml, $object->uid, $pay_type_string[$object->pay_type]);
                break;
            case 2 :
                VipLogic::instance()->handlePayCallBack($object->goods_id, $object->uid, $xml, $out_trade_no);
                break;
            default :
                Logger::instance()->wxPayCallback("【订单商品类型有误】:\n" . $xml . "\n");
                $this->updatePay($out_trade_no, '订单商品类型有误');
                break;
        }

        //更新订单成功标志
        $result = DB::table('t_pay_info')
            ->where('order_id', $out_trade_no)
            ->update([
                'order_status' => 1,
                'desc' => 'succ',
                'pay_time' => date('Y-m-d H:i:s', time())
            ]);
        if (!$result) {
            Logger::instance()->wxPayCallback("【更新订单状态失败】:\n" . $xml . "\n");
            //到了这一步,前面都没有错误,这一步出错了,需要回滚之前的操作
            DB::rollBack();
            $this->updatePay($out_trade_no, '更新订单状态失败');
        }
        DB::commit();

        Logger::instance()->wxPayCallback("【支付成功】:\n" . $xml . "\n");

        //每日充值任务
        $this->add_task_unclaimed_num($object->uid, 1);
    }


    //把订单状态改成付款失败 并抛出错误
    public function updatePay($order_id, $desc)
    {
        DB::table('t_pay_info')->where('order_id', $order_id)->update(['order_status' => -1, 'desc' => $desc]);
        //先把事物提交了,保证本次更改有效，如果不提交事物，将会被最外层try 捕获下面的throw到并进行回滚
        DB::commit();
        throw new ApiException('支付回调处理失败');
    }

    //每日任务未领取次数加一次
    private function add_task_unclaimed_num($uid, $taskid)
    {
        $cur_date      = date('Y-m-d', time());
        $unclaimed_key = 'task_unclaimed_' . (string)$taskid . '_' . $cur_date;
        Redis::hIncrBy($unclaimed_key, (string)$uid, 1);
        Redis::expire($unclaimed_key, 3600 * 24 * 2);
        return true;
    }


}